package org.dru.clay.respository.ivy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dru.clay.respository.dependency.ConfigurationMapping;
import org.dru.clay.respository.dependency.MappingRule;
import org.dru.clay.respository.dependency.MappingRules;

public class ConfigurationMappingParser {
	public static final Pattern arrow = Pattern.compile("(.*)->(.*)", Pattern.DOTALL);

	public ConfigurationMapping parse(String conf) {
		final List<MappingRule> rules = new ArrayList<MappingRule>();

		final String[] parts = conf.split(";");
		for (int i = 0; i < parts.length; i++) {
			final String part = parts[i].trim();

			if (parseArrow(rules, part)) {
				continue;
			}

			rules.add(MappingRules.simple(part));
		}

		return new ConfigurationMapping(rules);
	}

	private boolean parseArrow(List<MappingRule> rules, String part) {
		final Matcher matcher = arrow.matcher(part);
		if (!matcher.matches()) {
			return false;
		}
		String left = matcher.group(1).trim();
		String right = matcher.group(2).trim();

		if ("@".equals(right)) {
			right = left;
		}

		if (isAll(left)) {
			rules.add(MappingRules.anyToMany(csv(right)));
			return true;
		}

		rules.add(MappingRules.mayToMany(csv(left), csv(right)));
		return true;
	}

	private Collection<String> csv(String value) {
		final Set<String> result = new HashSet<String>();
		if (value != null) {
			final String[] part = value.split(",");
			for (int i = 0; i < part.length; i++) {
				result.add(part[i].trim());
			}
		}
		return result;
	}

	private boolean isAll(String s) {
		return "%".equals(s) || "*".equals(s);
	}
}
